// vmimage.hpp
// A VM image is the memory data-structure that the VM uses to interpret.
// The data-structure can be edited by the assembler/compiler.
// A VM image can be loaded from disk, and written to disk using save/load
// serialization.
//
// Copyright (C) 2008  Maksim Sipos <msipos@mailc.net>
//
// This file is a part of the Ripe language project.
//
// Ripe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifndef R_VMIMAGE_HPP
#define R_VMIMAGE_HPP

#include "util/standard.hpp"
#include "util/serialize.hpp"
#include "adts/vector.hpp"
#include "vm/vmunit.hpp"
#include "vm/vmdirect.hpp"

namespace Ripe {
  // VMSection flags:
  #define R_SECTION_CODE   1
  #define R_SECTION_SYMBOL 2
  #define R_SECTION_DIRECT 3

  class ErrorInvalidVMImage : public Exception {
    public:
      ErrorInvalidVMImage(const char* s);

      const char* what;
  };

  class VMSection {
    public:
      uint32_t flags; // These flags are any of those above.
      const char* name;

      virtual ~VMSection();
      virtual void save(OSerializer* stream) = 0;
      virtual void load(ISerializer* stream) = 0;
  };

  class VMSectionCode : public VMSection {
    public:
      VMSectionCode();

      Vector<Unit> units;

      // VMSectionCode specific serialization/unserialization
      void save(OSerializer* stream);
      void load(ISerializer* stream);
  };

  class VMSectionSymbol : public VMSection {
    public:
      VMSectionSymbol();

      Vector<char*> symbols;

      // VMSectionCode specific serialization/unserialization
      void save(OSerializer* stream);
      void load(ISerializer* stream);
  };

  class VMSectionDirect : public VMSection {
    public:
      VMSectionDirect();
      
      Vector<DirectValue> directs;
      
      // VMSectionDirect specific serialization/unserialization
      void save(OSerializer* stream);
      void load(ISerializer* stream);
  };

  class VMImage {
    public:
      // Load from a stream
      VMImage(ISerializer* stream);

      // Construct empty
      VMImage();

      Vector<VMSection*> sections;

      // Save to a stream
      void save(OSerializer* stream);
  };
}

#endif // R_VMIMAGE_HPP
